home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pp / pp-6.0 / Src / submit / auth.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-18  |  25.9 KB  |  1,282 lines

  1. /* auth.c: authorisation procedures used by submit */
  2.  
  3. # ifndef lint
  4. static char Rcsid[] = "@(#)$Header: /xtel/pp/pp-beta/Src/submit/RCS/auth.c,v 6.0 1991/12/18 20:28:02 jpo Rel $";
  5. # endif
  6.  
  7. /*
  8.  * $Header: /xtel/pp/pp-beta/Src/submit/RCS/auth.c,v 6.0 1991/12/18 20:28:02 jpo Rel $
  9.  *
  10.  * $Log: auth.c,v $
  11.  * Revision 6.0  1991/12/18  20:28:02  jpo
  12.  * Release 6.0
  13.  *
  14.  */
  15.  
  16.  
  17.  
  18. #include "head.h"
  19. #include "q.h"
  20. #include "dr.h"
  21. #include "tb_auth.h"
  22. #include <isode/cmd_srch.h>
  23.  
  24.  
  25.  
  26. #define ORED            FALSE
  27. #define freason(i)        (rcmd_srch (i, authtbl_reasons))
  28. #define rrights(i)        (rcmd_srch (i, authtbl_rights))
  29. #define gval(x)            ((x -> ad_type) == AD_X400_TYPE ? \
  30.                  (x -> ad_r400adr) : (x -> ad_r822adr))    
  31.  
  32.  
  33. extern CMD_TABLE        authtbl_rights[];
  34. extern CMD_TABLE        authtbl_loglevel[];
  35. extern LIST_AUTH_CHAN        *authchan_new();
  36. extern LIST_AUTH_MTA        *authmta_new ();
  37. extern AUTH_USER        *authusr_new();
  38. extern AUTH            *auth_new();
  39. extern char            *re_comp();
  40. extern CMD_TABLE        authtbl_reasons[];
  41. extern char                 *authchannel;
  42. extern char                 *authloglevel;
  43. extern char            *loc_dom_site;
  44. extern void            do_reason(), err_abrt();
  45. extern void            tb_parse_authchan();
  46. extern void            authchan_add(), authmta_add();
  47. /* -- static  variables -- */
  48. static AUTH                     *sender_auth    = NULL_AUTH;
  49. static LIST_AUTH_CHAN        *def_authchan    = NULLIST_AUTHCHAN;
  50. static LIST_AUTH_CHAN        *authchan_start = NULLIST_AUTHCHAN;
  51. static LIST_AUTH_MTA        *authmta_start    = NULLIST_AUTHMTA;
  52.  
  53.  
  54. /* -- globals -- */
  55. char                auth2submit_msg[BUFSIZ];
  56. int                auth_loglev;
  57.  
  58.  
  59. /* -- local routines -- */
  60. int                 auth_finish();
  61. int                fillin_orig_outchan();
  62. void                auth_start();
  63.  
  64. static Bindings            *bindings_new();
  65. static Bindings            *do_ch_binds();
  66. static char            *ltoa();
  67. static int            test_pair();
  68. static int            bindings_free();
  69. static int            chk_mtarights();
  70. static int            chk_usrights();
  71. static int            do_stage_1();
  72. static int            do_stage_2();
  73. static int            test_flags();
  74. static int            test_recip_finish();
  75. static int            test_recip_start();
  76. static int            test_regex();
  77. static void            auth_chan();
  78. static void            auth_err2adr();
  79. static void            auth_init();
  80. static void            auth_init_recip();
  81. static void            auth_mta();
  82. static void            auth_remdup();
  83. static void            auth_usr();
  84. static void            auth_usr_chks();
  85. static void            bindings_add();
  86. static void            pr_rights();
  87. static void            rem_excess_outchans();
  88. static void            rem_pair();
  89. static void            set_fmt_and_content();
  90.  
  91.  
  92.  
  93.  
  94. /* ------------------------  Begin  Routines  ------------------------------- */
  95.  
  96.  
  97.  
  98.  
  99. void auth_start(que, sender, recip)
  100. Q_struct *que;
  101. ADDR    *sender, *recip;
  102. {
  103.         ADDR   *ad;
  104.  
  105.         PP_TRACE (("auth_start()"));
  106.  
  107.         auth_init(que, recip);
  108.         auth_usr(sender, recip);    
  109.  
  110.         for (ad = recip; ad; ad = ad -> ad_next)
  111.                 if (ad -> ad_status == AD_STAT_PEND)
  112.                         test_recip_start (que, sender, ad);
  113. }
  114.  
  115.  
  116.  
  117.  
  118.  
  119. int  auth_finish(qp, sender, recip)
  120. Q_struct *qp;
  121. ADDR    *sender, *recip;
  122. {
  123.         ADDR    *ad;
  124.         int     retval = RP_OK;
  125.  
  126.         for (ad = recip; ad; ad = ad -> ad_next) {
  127.  
  128.         PP_TRACE (("auth_finish ('%s', '%d')",
  129.             ad -> ad_value, ad -> ad_status));
  130.  
  131.         switch (ad -> ad_status) { 
  132.         case AD_STAT_PEND:
  133.                         if (test_recip_finish (qp, sender, ad) == NOTOK)
  134.                 retval = RP_NAUTH;
  135.             continue;
  136.         default:
  137.             continue;
  138.         }
  139.     }    
  140.  
  141.         PP_TRACE (("auth_finish returns ('%s')", rp_valstr (retval)));
  142.         return retval;
  143. }
  144.  
  145.  
  146.  
  147.  
  148. int fillin_orig_outchan (qp, ad) 
  149. Q_struct *qp;
  150. ADDR    *ad;
  151. {
  152.     Bindings    *binds, *ix;
  153.     int        unknownBP;
  154.     if ((binds = do_ch_binds (qp, ad, &unknownBP)) == (Bindings *) NULL) {
  155.         PP_LOG(LLOG_EXCEPTIONS,
  156.                ("Unable to reformat return of contents"));
  157.         /* take first channel */
  158.         rem_excess_outchans(ad, ad->ad_outchan);
  159.         ad->ad_type = ad->ad_outchan->li_chan->ch_out_ad_type;
  160.         return OK;
  161.     }
  162.  
  163.     /* try for one without reformatting ? */
  164.     /* should also check unknownBP */
  165.     for (ix = binds;ix && ix -> fmtchans;ix = ix->next)
  166.         continue;
  167.     if (!ix) {
  168.         /* revert to first choice */
  169.         ix = binds;
  170. #ifdef    NOTDEF
  171.         if (unknownBP == TRUE) {
  172.             /* oh oh unknown bodypart and reformatting */
  173.             /* just have to forget about return of contents */
  174.             list_rchan_free(ix -> fmtchans);
  175.             ix -> fmtchans = NULLIST_RCHAN;
  176.         }
  177. #endif
  178.     }
  179.  
  180.     set_fmt_and_content(qp, ad, ix);
  181.  
  182.     rem_excess_outchans (ad, ix -> outchan);
  183.     ad -> ad_type = ix -> outchan -> li_chan -> ch_out_ad_type;
  184.     bindings_free (binds);
  185.     return OK;
  186. }    
  187.  
  188.  
  189.  
  190.  
  191. /* ------------------------  Static Routines  ------------------------------- */
  192.  
  193.  
  194.  
  195.  
  196. static int bindings_free (ix)
  197. Bindings    *ix;
  198. {
  199.     if (ix == NULL) return;
  200.     if (ix -> next != (Bindings *) NULL) bindings_free (ix -> next);
  201.     list_rchan_free (ix -> fmtchans);
  202.     list_bpt_free (ix -> bpts);
  203.     free ((char *) ix);
  204. }
  205.  
  206.  
  207.  
  208. static Bindings    *bindings_new (out, fmts, bpts, cost)
  209. LIST_RCHAN    *out,
  210.         *fmts;
  211. LIST_BPT    *bpts;
  212. int        cost;
  213. {
  214.     Bindings    *ret = (Bindings *) malloc(sizeof(Bindings));
  215.     ret -> outchan = out;
  216.     ret -> fmtchans = fmts;
  217.     ret -> bpts = bpts;
  218.     ret -> cost = cost;
  219.     ret -> next = (Bindings *) NULL;
  220.     return ret;
  221. }
  222.  
  223.  
  224.  
  225. static void bindings_add (plist, new)
  226. Bindings    **plist,
  227.         *new;
  228. {
  229.     Bindings    *ix;
  230.  
  231.     PP_TRACE (("bindings_add ('%s')",
  232.         new -> outchan -> li_chan -> ch_name));
  233.  
  234.     if (*plist == (Bindings *) NULL
  235.         || new -> cost < (*plist) -> cost) {
  236.         /* easy */
  237.         new -> next = *plist;
  238.         *plist = new;
  239.         return;
  240.     }
  241.     
  242.     ix = *plist;
  243.     
  244.     while (ix -> next != (Bindings *) NULL
  245.            && ix -> next -> cost <= new -> cost)
  246.         ix = ix -> next;
  247.     new -> next = ix -> next;
  248.     ix -> next = new;
  249. }
  250.     
  251.  
  252.  
  253. static Bindings    *do_ch_binds (qp, ad, punknown)
  254. Q_struct *qp;
  255. ADDR    *ad;
  256. int    *punknown;
  257. {
  258.     Bindings    *ret = (Bindings *) NULL;
  259.     LIST_RCHAN    *ix = ad -> ad_outchan, *fmts;
  260.     LIST_BPT    *bpts;
  261.     int        cost, unknown;
  262.  
  263.     *punknown = FALSE;
  264.     
  265.     while (ix != NULLIST_RCHAN) {
  266.         PP_TRACE (("do_ch_binds ('%s')", ix -> li_chan -> ch_name));
  267.         if (ch_bind (qp, ad, ix, &fmts, &bpts, &cost, &unknown) == OK) {
  268.             bindings_add(&ret, bindings_new(ix, fmts, bpts, cost));
  269.             if (unknown == TRUE)
  270.                 *punknown = TRUE;
  271.         }
  272.         ix = ix -> li_next;
  273.     }
  274.     return ret;
  275. }
  276.  
  277.  
  278.  
  279.  
  280. static int test_recip_finish (qp, orig, ad)
  281. Q_struct *qp;
  282. ADDR    *orig, *ad;
  283. {
  284.     Bindings    *binds, *ix;
  285.     int        retval = OK, unknownBP;
  286.     int        test = ad -> ad_outchan -> li_auth -> chan -> test; 
  287.  
  288.     PP_TRACE (("test_recip_finish : %s", gval(ad)));
  289.     
  290.     if ((binds = do_ch_binds (qp, ad, &unknownBP)) == (Bindings *) NULL) 
  291.         return NOTOK;
  292.     
  293.     for (ix = binds; ix != (Bindings *) NULL; ix = ix -> next) {
  294.         
  295.         if (unknownBP == TRUE
  296.             && ix -> fmtchans)
  297.             continue;
  298.  
  299.         switch (ix -> outchan -> li_auth -> status) {
  300.         case AUTH_OK:
  301.         case AUTH_DR_OK:
  302.             ad -> ad_type = ix -> outchan -> li_chan -> ch_out_ad_type;
  303.             retval = test_pair (qp, ad, ix -> outchan, orig);
  304.  
  305.             if (retval == NOTOK) {
  306.                 rem_pair (qp, ad, ix -> outchan);
  307.                 if (test != AUTH_CHAN_TEST) 
  308.                     continue;
  309.             }
  310.  
  311.             /* --- otherwise fall through --- */
  312.  
  313.         case AUTH_FAILED_TEST:    /* --- failed at do_stage_1 --- */
  314.             set_fmt_and_content (qp, ad, ix);
  315.             rem_excess_outchans (ad, ix -> outchan);
  316.             bindings_free (binds);
  317.             return OK;
  318.  
  319.         default:
  320.             continue;
  321.         }
  322.     }
  323.  
  324.     if (unknownBP == TRUE && ad -> ad_status != AD_STAT_DRREQUIRED) {
  325.         /* failed because of unknown bodypart */
  326.         ad -> ad_status = AD_STAT_DRREQUIRED;
  327.         ad -> ad_reason = DRR_CONVERSION_NOT_PERFORMED;
  328.         ad -> ad_diagnostic = DRD_CONVERSION_IMPRACTICAL;
  329.         ad -> ad_add_info = strdup("Unrecognised bodypart in message");
  330.     }
  331.     bindings_free (binds);
  332.     return NOTOK;
  333. }
  334.  
  335.  
  336.  
  337.  
  338. static void set_fmt_and_content (qp, ad, ix)
  339. Q_struct *qp;
  340. ADDR        *ad;
  341. Bindings    *ix;
  342. {
  343.     char    *content_out = ix -> outchan -> li_chan -> ch_content_out;
  344.  
  345.     PP_TRACE (("submit/Give message to '%s'",
  346.         ix -> outchan -> li_chan -> ch_name));
  347.  
  348.     ad -> ad_fmtchan = ix -> fmtchans;
  349.  
  350.     /* -- stop them being freed -- */
  351.     ix -> fmtchans = NULLIST_RCHAN;
  352.     ad -> ad_eit = ix -> bpts;
  353.  
  354.     /* -- stop them being freed -- */
  355.     ix -> bpts = NULLIST_BPT;
  356.     if (ad -> ad_content != NULLCP) { 
  357.         free (ad -> ad_content);
  358.         ad -> ad_content = NULLCP;
  359.     }
  360.  
  361.     if (isstr (qp -> cont_type) && 
  362.         isstr (content_out) &&
  363.         strcmp (qp -> cont_type, content_out) != 0)
  364.             ad -> ad_content = strdup (content_out);
  365.     else if (isstr (content_out))
  366.             ad -> ad_content = strdup (content_out);
  367.  
  368.     return;
  369. }
  370.  
  371.  
  372.  
  373.  
  374. static int test_recip_start (qp, orig, ad)
  375. Q_struct *qp;
  376. ADDR   *orig, *ad;
  377. {
  378.     LIST_RCHAN    *lp = ad -> ad_outchan;
  379.     int        retval = FALSE;
  380.  
  381.     PP_TRACE (("test_recip_start : %s", gval(ad)));
  382.  
  383.     for (; lp != NULLIST_RCHAN; lp = lp -> li_next) {
  384.  
  385.         ad -> ad_type = lp -> li_chan -> ch_out_ad_type;
  386.  
  387.         switch (lp -> li_auth -> status) {
  388.         case AUTH_OK:
  389.         case AUTH_DR_OK:
  390.             retval = test_pair (qp, ad, lp, orig);
  391.             if (retval == OK)  return OK;
  392.             rem_pair (qp, ad, lp);
  393.             continue;
  394.         default:
  395.             continue;
  396.         }
  397.     }
  398.  
  399.     return retval;
  400. }
  401.  
  402.  
  403.  
  404. static int  test_pair (qp, ad, lp, orig)  /* Test chan/mta/usr per recip */
  405. Q_struct *qp;
  406. ADDR           *ad;
  407. LIST_RCHAN     *lp;
  408. ADDR    *orig;
  409. {
  410.     char        *val = gval(ad);
  411.     AUTH        *au = lp -> li_auth;
  412.     int        retval;    
  413.  
  414.     PP_TRACE (("test_pair : '%s' '%s' '%s'", val,
  415.         au -> chan -> li_chan -> ch_name, au -> mta -> li_mta));
  416.  
  417.  
  418.  
  419.     switch (au -> stage) {
  420.  
  421.     case AUTH_STAGE_1:
  422.         if (au -> chan -> li_found == FALSE)
  423.             auth_chan (au -> chan);
  424.         retval = do_stage_1 (qp, ad, au, orig);
  425.         return retval;
  426.  
  427.  
  428.     case AUTH_STAGE_2: 
  429.         retval = do_stage_2 (qp, val, au);
  430.         return retval;
  431.     }
  432.  
  433.  
  434.     PP_LOG (LLOG_EXCEPTIONS, 
  435.         ("auth/Internal error unknown test stage %d", au -> stage));
  436.     return NOTOK;
  437. }
  438.  
  439.  
  440. static void auth_user (au, ad)
  441. AUTH    *au;
  442. ADDR    *ad;
  443. {
  444.     if (au -> user -> found == TRUE)
  445.         return;
  446.  
  447.     if (tb_getauthusr (au -> user, ad) == NOTOK)
  448.         err_abrt (RP_NAUTH, "Cannot look up authorisation for '%s'",
  449.               gval(ad));
  450.     if (au -> user -> found == FALSE)
  451.         PP_TRACE (("auth_usr_chks/recipient '%s' missing",
  452.                gval (ad)));
  453. }
  454.  
  455. static int do_stage_1 (qp, ad, au, orig)
  456. Q_struct *qp;
  457. ADDR    *ad;
  458. AUTH    *au;
  459. ADDR    *orig;
  460. {
  461.  
  462.     int        t[4];
  463.     int        i = 0;
  464.     int        retval = NOTOK;
  465.     char        buf[LINESIZE];
  466.     LIST_REGEX    *lr;
  467.  
  468.  
  469.     PP_TRACE (("do_stage_1: %s", gval(ad)));
  470.  
  471.     switch (au -> chan -> policy) {
  472.  
  473.     default:
  474.         PP_LOG (LLOG_EXCEPTIONS,
  475.             ("auth/do_stage_1 unknown channel policy %d",
  476.              au -> chan -> policy));
  477.         break;
  478.  
  479.     case AUTH_CHAN_FREE:
  480.         do_reason (au, freason(AUR_CH_FREE));
  481.         retval = OK;
  482.         break;
  483.  
  484.  
  485.     case AUTH_CHAN_NONE:
  486.         do_reason (au, freason(AUR_CH_NONE));
  487.         break;
  488.  
  489.  
  490.     case AUTH_CHAN_NEGATIVE:
  491.         auth_mta (au);
  492.         auth_mta (sender_auth);
  493.         auth_user (sender_auth, orig);
  494.         auth_user (au, ad);
  495.  
  496.         t [i++] = chk_mtarights (qp, sender_auth,
  497.                      au -> chan -> li_chan); 
  498.         t [i++] = chk_usrights (qp, sender_auth,
  499.                     au -> chan -> li_chan);
  500.         t [i++] = chk_mtarights (qp, au, au -> chan -> li_chan);
  501.         t [i++] = chk_usrights (qp, au, au -> chan -> li_chan);
  502.  
  503.         /* with negative, OK means one of the values is true,
  504.          *  which in turn means there is an explicit block on this
  505.          *   which means its failed authorisation */
  506.         if (test_flags (t, NOTOK, ORED) != OK)
  507.             retval = OK;
  508.         pr_rights (au, AUTH_CHAN_NEGATIVE, retval);
  509.         break;
  510.  
  511.  
  512.     case AUTH_CHAN_BLOCK:
  513.         auth_mta (au);
  514.         auth_mta (sender_auth);
  515.         auth_user (sender_auth, orig);
  516.         auth_user (au, ad);
  517.         t [i++] = chk_mtarights (qp, sender_auth,
  518.                      au -> chan -> li_chan);
  519.         t [i++] = chk_usrights (qp, sender_auth,
  520.                     au -> chan -> li_chan);
  521.         t [i++] = chk_mtarights (qp, au, au -> chan -> li_chan);
  522.         t [i++] = chk_usrights (qp, au, au -> chan -> li_chan);
  523.         retval = test_flags (t, OK, ORED);
  524.         pr_rights (au, AUTH_CHAN_BLOCK, retval);
  525.         break;
  526.     }
  527.  
  528.  
  529.  
  530.     if (retval == NOTOK)
  531.         return NOTOK;
  532.  
  533.  
  534.     /* -- regex testing -- */
  535.  
  536.     bzero (buf, LINESIZE); 
  537.  
  538.     lr = sender_auth -> mta -> requires;
  539.     if (lr && (!test_regex (gval (orig), lr, buf))) {
  540.         do_reason (au, freason(AUR_IMTA_MISSING_SNDR), buf);
  541.         return NOTOK;    
  542.     }
  543.  
  544.     lr = sender_auth -> mta -> excludes;
  545.     if (lr && (test_regex (gval (orig), lr, buf))) {
  546.         do_reason (au, freason(AUR_IMTA_EXCLUDES_SNDR), buf);
  547.         return NOTOK;
  548.     }
  549.  
  550.     lr = au -> mta -> requires; 
  551.     if (lr && (!test_regex (gval(ad), lr, buf))) {
  552.         do_reason (au, freason(AUR_OMTA_MISSING_RECIP), buf);
  553.         return NOTOK;
  554.     }
  555.  
  556.     lr = au -> mta -> excludes;
  557.     if (lr && (test_regex (gval(ad), lr, buf))) {
  558.         do_reason (au, freason(AUR_OMTA_EXCLUDES_RECIP), buf);
  559.         return NOTOK;
  560.     }
  561.  
  562.     au -> stage = AUTH_STAGE_2;
  563.     return OK;
  564. }
  565.  
  566.  
  567.  
  568.  
  569. static int do_stage_2 (qp, adval, au)
  570. Q_struct *qp;
  571. char    *adval;
  572. AUTH    *au;
  573. {
  574.     LIST_BPT    *le, *lb;
  575.     long        size;
  576.  
  577.  
  578.     PP_TRACE (("do_stage_2: %s", adval));
  579.  
  580.     /* -- content tests -- */
  581.  
  582.     size = au -> chan -> sizelimit;
  583.     if (size && (qp -> msgsize > size)) {
  584.         do_reason (au, freason(AUR_MSGSIZE_FOR_CHAN),
  585.             ltoa(qp -> msgsize), ltoa(size));
  586.         return NOTOK;
  587.     }
  588.  
  589.     size = au -> mta -> sizelimit;
  590.     if (size && (qp -> msgsize > size)) {
  591.         do_reason (au, freason(AUR_MSGSIZE_FOR_MTA),
  592.             ltoa(qp -> msgsize), ltoa(size));
  593.         return NOTOK;
  594.     }
  595.  
  596.     size = au -> user -> sizelimit;
  597.     if (size && (qp -> msgsize > size)) {
  598.         do_reason (au, freason(AUR_MSGSIZE_FOR_USR),
  599.             ltoa(qp -> msgsize), ltoa(size));
  600.         return NOTOK;
  601.     }
  602.  
  603.  
  604.     /* -- body part tests -- */
  605.  
  606.  
  607.     for (le = au -> mta -> content_excludes; le; le = le -> li_next) {
  608.         for (lb = qp->encodedinfo.eit_types; lb; lb = lb -> li_next) {
  609.  
  610.             PP_TRACE (("do_stage_2 exclude mta body parts %s : %s",
  611.                 le -> li_name, lb -> li_name));
  612.  
  613.             if (strcmp (le -> li_name, lb -> li_name) ==  0) {
  614.                 do_reason (au, freason(AUR_MTA_BPT),
  615.                         le -> li_name);
  616.                 return NOTOK;
  617.             }
  618.         }
  619.     }
  620.  
  621.  
  622.     for (le = au -> user -> content_excludes; le; le = le -> li_next) {
  623.         for (lb = qp->encodedinfo.eit_types; lb; lb=lb -> li_next) {
  624.  
  625.             PP_TRACE (("do_stage_2 exclude user body parts %s : %s",
  626.                 le -> li_name, lb -> li_name));
  627.  
  628.             if (strcmp (le -> li_name, lb -> li_name) ==  0) {
  629.                 do_reason (au, freason(AUR_USR_BPT),
  630.                         le -> li_name);
  631.                 return NOTOK;
  632.             }
  633.         }
  634.     }
  635.  
  636.  
  637.     au -> stage ++;
  638.     PP_TRACE (("do_stage_2:  successful & returns '%s'", au -> reason));
  639.     return OK;
  640. }
  641.  
  642.  
  643.  
  644.  
  645. static int test_regex (val, list, ptr)
  646. char        *val;
  647. LIST_REGEX    *list;
  648. char        *ptr;
  649. {
  650.     LIST_REGEX    *lr;
  651.     char        *cp;
  652.     int        test;
  653.  
  654.     PP_TRACE (("test_regex: %s", val));
  655.  
  656.     for (lr = list; lr != NULLIST_REGEX; lr = lr -> li_next) {
  657.  
  658.         PP_TRACE (("auth/test_regex: '%s'", lr -> li_regex));
  659.  
  660.         cp = re_comp (lr -> li_regex);
  661.  
  662.         if (cp) {
  663.             PP_LOG (LLOG_EXCEPTIONS, 
  664.             ("auth/test_regex: invalid expression <%s> %s",
  665.             lr -> li_regex, cp));
  666.             continue;
  667.         }
  668.  
  669.         test = re_exec (val);
  670.  
  671.         if (test == 1) {
  672.             (void) sprintf (ptr, "%s", lr -> li_regex);
  673.             PP_TRACE (("auth/test_regex : %s matches %s",
  674.                 val, lr -> li_regex));
  675.             return TRUE;
  676.         }
  677.  
  678.  
  679.         if (test == -1) {
  680.             PP_LOG (LLOG_EXCEPTIONS, 
  681.             ("auth/test_regex : internal error <%s>",
  682.             lr -> li_regex));
  683.             continue;
  684.         }
  685.  
  686.  
  687.         if (strlen (ptr)) {
  688.             (void) strcat (ptr, " | ");
  689.             (void) strcat (ptr, lr -> li_regex);
  690.         }
  691.         else 
  692.             (void) sprintf (ptr, "%s", lr -> li_regex);
  693.  
  694.         PP_TRACE (("auth/test_regex: no match: %s : %s", 
  695.             lr -> li_regex, ptr));
  696.  
  697.         continue;
  698.     }
  699.  
  700.     return FALSE;
  701. }
  702.  
  703.  
  704.  
  705.  
  706. static int chk_mtarights (qp, au, ch)  
  707. Q_struct *qp;
  708. AUTH    *au;
  709. CHAN    *ch;
  710. {
  711.     int            infound = FALSE,
  712.                 outfound = FALSE;
  713.     LIST_CHAN_RIGHTS    *lr;
  714.  
  715.  
  716.     PP_TRACE (("chk_mtarights()"));
  717.  
  718.     if (au -> mta -> li_found == FALSE)  return MAYBE;
  719.  
  720.     if (au -> mta -> rights != AUTH_RIGHTS_UNSET) {
  721.         au -> mta_inrights  = au -> mta -> rights; 
  722.         au -> mta_outrights = au -> mta -> rights;
  723.     }
  724.  
  725.  
  726.     for (lr = au -> mta -> li_cr; lr; lr = lr -> li_next) {
  727.         if (lr -> li_chan == qp -> inbound -> li_chan) {
  728.             infound = TRUE;
  729.             au -> mta_inrights = lr -> li_rights;
  730.         }
  731.  
  732.         if (lr -> li_chan == ch) {
  733.             outfound = TRUE;
  734.             au -> mta_outrights = lr -> li_rights;
  735.         }
  736.  
  737.         if (infound && outfound)
  738.             break;
  739.     }
  740.  
  741.  
  742.     /* -- returns OK if (inbound = in|both && outbound = out|both -- */
  743.  
  744.     if (au -> mta_inrights == AUTH_RIGHTS_NONE || 
  745.         au -> mta_inrights == AUTH_RIGHTS_OUT || 
  746.         au -> mta_inrights == AUTH_RIGHTS_UNSET) 
  747.         return NOTOK;    
  748.  
  749.     if (au -> mta_outrights == AUTH_RIGHTS_NONE ||
  750.         au -> mta_outrights == AUTH_RIGHTS_IN ||
  751.         au -> mta_outrights == AUTH_RIGHTS_UNSET) 
  752.         return NOTOK;
  753.  
  754.     PP_TRACE (("chk_mtarights : successful: in = %s  out = %s", 
  755.            rrights (au -> mta_inrights), 
  756.            rrights (au -> mta_outrights)));
  757.  
  758.     return OK;
  759. }
  760.  
  761. static int chk_usrights (qp, au, ch)
  762. Q_struct *qp;
  763. AUTH    *au;
  764. CHAN    *ch;
  765. {
  766.     int            infound = FALSE, 
  767.                 outfound = FALSE; 
  768.     LIST_CHAN_RIGHTS    *lr;
  769.  
  770.  
  771.     PP_TRACE (("chk_usrights()"));
  772.  
  773.     if (au -> user -> found == FALSE)
  774.         return MAYBE;
  775.  
  776.     if (au -> user -> rights != AUTH_RIGHTS_UNSET) {
  777.         au -> user_inrights = au -> user -> rights;
  778.         au -> user_outrights = au -> user -> rights;
  779.     }
  780.  
  781.     for (lr = au -> user -> li_cr; lr; lr = lr -> li_next) {
  782.         if (lr -> li_chan == qp -> inbound -> li_chan) {
  783.             infound = TRUE;
  784.             au -> user_inrights = lr -> li_rights;
  785.         }
  786.  
  787.         if (lr -> li_chan == ch) {
  788.             outfound = TRUE;
  789.             au -> user_outrights = lr -> li_rights;
  790.         }
  791.  
  792.         if (infound && outfound)
  793.             break;
  794.     }
  795.  
  796.  
  797.     /* -- returns OK if (inbound = in|both && outbound = out|both -- */
  798.  
  799.     if (au -> user_inrights == AUTH_RIGHTS_NONE || 
  800.         au -> user_inrights == AUTH_RIGHTS_OUT || 
  801.         au -> user_inrights == AUTH_RIGHTS_UNSET) 
  802.             return NOTOK;
  803.  
  804.     if (au -> user_outrights == AUTH_RIGHTS_NONE || 
  805.         au -> user_outrights == AUTH_RIGHTS_IN || 
  806.         au -> user_outrights == AUTH_RIGHTS_UNSET)
  807.             return NOTOK;
  808.  
  809.     PP_TRACE (("chk_usrights : successful : in = %s  out = %s", 
  810.         rrights (au -> user_inrights), 
  811.         rrights (au -> user_outrights)));
  812.  
  813.     return OK;
  814. }
  815.  
  816. static void rem_excess_outchans (ad, outchan)
  817. ADDR    *ad;
  818. LIST_RCHAN    *outchan;
  819. {
  820.     LIST_RCHAN    *ix, *tmp;
  821.  
  822.     /* remove excess ad_outchans */
  823.     
  824.     ix = ad -> ad_outchan;
  825.  
  826.     if (ix != outchan) {
  827.         while (ix -> li_next != NULLIST_RCHAN
  828.                && ix -> li_next != outchan)
  829.             ix = ix -> li_next;
  830.         if (ix -> li_next != NULLIST_RCHAN) {
  831.             tmp = ad -> ad_outchan;
  832.             ad -> ad_outchan = ix -> li_next;
  833.             ix -> li_next = NULLIST_RCHAN;
  834.             list_rchan_free (tmp);
  835.         }    
  836.     }
  837.     
  838.     if (ad -> ad_outchan -> li_next != NULLIST_RCHAN) {
  839.         list_rchan_free (ad -> ad_outchan -> li_next);
  840.         ad -> ad_outchan -> li_next = NULLIST_RCHAN;
  841.     }
  842. }
  843.  
  844.  
  845.  
  846.  
  847. static void rem_pair (qp, ad, remch)
  848. Q_struct    *qp;
  849. ADDR        *ad;
  850. LIST_RCHAN    *remch;
  851. {
  852.     LIST_RCHAN    *lp;
  853.     AUTH        *au = remch -> li_auth;
  854.     int        allgone = TRUE;
  855.  
  856.  
  857.     if (remch == NULLIST_RCHAN)  return;
  858.  
  859.  
  860.     PP_TRACE (("rem_pair : '%s' '%s' '%s' '%d'", 
  861.         gval (ad), remch -> li_chan -> ch_name,
  862.         remch -> li_mta, au -> chan -> test));
  863.  
  864.  
  865.     switch (au -> chan -> test) { 
  866.     case AUTH_CHAN_TEST:  
  867.         au -> status = AUTH_FAILED_TEST;
  868.         return;
  869.     default:
  870.         au -> status = AUTH_FAILED;
  871.         break;
  872.     }
  873.  
  874.  
  875.     for (lp = ad -> ad_outchan; lp; lp = lp -> li_next) {
  876.         switch (lp -> li_auth -> status) {
  877.             case AUTH_OK:
  878.             case AUTH_DR_OK:
  879.             case AUTH_FAILED_TEST:
  880.             allgone = FALSE;
  881.             break;
  882.  
  883.             case AUTH_DR_FAILED:
  884.             case AUTH_FAILED:
  885.             continue;
  886.         }
  887.         break;
  888.     }
  889.  
  890.     if (allgone)
  891.         auth_err2adr (qp, ad);
  892. }
  893.  
  894.  
  895.  
  896.  
  897. static void auth_err2adr (qp, ad)
  898. Q_struct    *qp;
  899. ADDR           *ad;
  900. {
  901.     char    buf [BUFSIZ * 2];
  902.     int    oldType;
  903.     if (ad == NULLADDR)                return;
  904.  
  905.     ad -> ad_status        = AD_STAT_DRREQUIRED;
  906.     ad -> ad_reason        = DRR_UNABLE_TO_TRANSFER;
  907.     ad -> ad_diagnostic = DRD_NO_BILATERAL_AGREEMENT;
  908.  
  909.     oldType = ad->ad_type;
  910.     if (qp && qp -> inbound && qp -> inbound -> li_chan)
  911.         ad->ad_type = qp -> inbound -> li_chan -> ch_in_ad_type;
  912.     (void) sprintf (buf, 
  913.           "Authorisation failure at site '%s' for recip '%s' Reason: '%s'",
  914.           loc_dom_site, gval(ad), auth2submit_msg);
  915.     ad->ad_type = oldType;
  916.  
  917.     ad -> ad_add_info   = strdup (buf);
  918.  
  919.     PP_TRACE (("auth_err2adr: '%s'", buf));
  920. }
  921.  
  922.  
  923.  
  924.  
  925. static void auth_chan (ch)
  926. LIST_AUTH_CHAN    *ch;
  927. {
  928.     if (tb_getauthchan (ch) == NOTOK)
  929.         err_abrt (RP_NAUTH,
  930.               "Cannot look up channel authorisation table '%s'",
  931.               ch -> li_chan -> ch_name);
  932.  
  933.     if (ch -> li_found == FALSE)
  934.         PP_TRACE (("auth_chan/Chan '%s' missing",
  935.                ch -> li_chan -> ch_name));
  936. }
  937.  
  938.  
  939.  
  940.  
  941. static void auth_mta (au)
  942. AUTH    *au;
  943. {
  944.     if (au -> mta -> li_found == TRUE)
  945.         return;
  946.     if (tb_getauthmta (au -> mta) == NOTOK)
  947.         err_abrt (RP_NAUTH,
  948.               "Cannot look up mta authorisation table '%s'",
  949.               au -> mta -> li_mta);
  950.  
  951.     if (au -> mta -> li_found == FALSE)
  952.         PP_TRACE (("auth_mta/Mta '%s' missing",
  953.                au -> mta -> li_mta));
  954. }
  955.  
  956.  
  957.  
  958.  
  959. static void auth_usr(orig, recip)
  960. ADDR *orig, *recip;
  961. {
  962.     ADDR   *ad;
  963.     int ac;
  964.  
  965.     PP_TRACE (("auth_usr()"));
  966.  
  967.     if (sender_auth -> user == NULL_AUTHUSR) 
  968.         err_abrt (RP_NAUTH, "No sender user authorisation table");
  969.  
  970.     if (orig == NULLADDR) 
  971.         err_abrt (RP_NAUTH, "No sender address found");
  972.  
  973. #ifdef notdef
  974.     if (tb_getauthusr (sender_auth -> user, orig) == NOTOK)
  975.         err_abrt (RP_NAUTH,
  976.               "Authorisation lookup failed for sender '%s'", 
  977.               gval (orig));
  978.  
  979.     if (sender_auth -> user -> found == FALSE) 
  980.         PP_TRACE (("auth_usr/sender user '%s' missing",
  981.                gval (orig)));
  982. #endif
  983.  
  984.     for (ad = recip, ac = 0; ad; ac ++,ad = ad -> ad_next) 
  985.         auth_usr_chks (ad);
  986.  
  987.  
  988.     if (ac > 1000)
  989.         return;
  990.     /* -- eliminate duplicates -- */
  991.  
  992.     for (ad = recip; ad; ad = ad -> ad_next) {
  993.  
  994.         PP_TRACE (("auth_usr/dup loop '%s' stat='%d', resp='%d')",
  995.             ad -> ad_value, ad -> ad_status, ad -> ad_resp));
  996.  
  997.         if (ad -> ad_resp == FALSE)
  998.             continue;
  999.  
  1000.         switch (ad -> ad_status) { 
  1001.         case AD_STAT_DRREQUIRED:
  1002.         case AD_STAT_DONE:
  1003.             continue;
  1004.         }
  1005.  
  1006.         auth_remdup (ad, ad -> ad_next);
  1007.     }
  1008. }
  1009.  
  1010.  
  1011.  
  1012.  
  1013. static void auth_usr_chks (ad)
  1014. ADDR    *ad;
  1015. {
  1016.     char    *value = ad -> ad_value;
  1017.  
  1018.     PP_TRACE (("auth_usr_chks (%s)", gval (ad)));
  1019.  
  1020.     if (ad -> ad_status == AD_STAT_DRREQUIRED || 
  1021.         ad -> ad_status == AD_STAT_DRWRITTEN ||
  1022.         ad -> ad_resp == FALSE) {
  1023.             PP_TRACE (("auth_usr/recip='%s' stat=%d resp=%d",
  1024.                 value, ad -> ad_status, ad -> ad_resp));
  1025.             return;
  1026.     }
  1027.  
  1028.     if (ad -> ad_outchan == NULL)
  1029.         err_abrt (RP_NAUTH, "ad_outchan unset for '%s'",
  1030.             value);
  1031.  
  1032.     if (ad -> ad_outchan -> li_auth == NULL_AUTH)
  1033.         err_abrt (RP_NAUTH, "chan auth unset for '%s'",
  1034.             value);
  1035. #ifdef notdef
  1036.     if (tb_getauthusr (ad -> ad_outchan -> li_auth -> user, ad) == NOTOK)
  1037.         err_abrt (RP_NAUTH, "Cannot look up authorisation for '%s'",
  1038.             value);
  1039.  
  1040.     if (ad -> ad_outchan -> li_auth -> user -> found == FALSE)
  1041.         PP_TRACE (("auth_usr_chks/recipient '%s' missing", gval (ad)));
  1042. #endif
  1043. }
  1044.  
  1045.  
  1046.  
  1047.  
  1048. static void auth_remdup (ad, list)  /* -- removes duplicates -- */
  1049. ADDR    *ad;
  1050. ADDR    *list;
  1051. {
  1052.     AUTH    *au;
  1053.  
  1054.     PP_TRACE (("auth_remdup (%s)", gval (ad)));
  1055.  
  1056.     for (list = ad -> ad_next; list; list = list -> ad_next) {
  1057.  
  1058.         PP_TRACE (("auth_remdup/'%s' stat='%d', resp='%d')",
  1059.             list -> ad_value, list -> ad_status, list -> ad_resp));
  1060.  
  1061.         if (list -> ad_resp == FALSE)
  1062.             continue;
  1063.  
  1064.         switch (list -> ad_status) { 
  1065.         case AD_STAT_DRREQUIRED:
  1066.         case AD_STAT_DONE:
  1067.             continue;
  1068.         }
  1069.  
  1070.  
  1071.         if (strcmp (gval(ad), gval(list)) == 0) {
  1072.  
  1073.             PP_TRACE (("auth_remdup/removed: '%s' (%d)",
  1074.                 gval (list), list -> ad_no));
  1075.  
  1076.             list -> ad_status = AD_STAT_DONE;
  1077.             list -> ad_outchan -> li_next = NULLIST_RCHAN;
  1078.  
  1079.             au = list -> ad_outchan -> li_auth;
  1080.             au -> status = AUTH_OK;
  1081.             do_reason (au, freason (AUR_DUPLICATE_REMOVED)); 
  1082.         }
  1083.     }
  1084. }
  1085.  
  1086.  
  1087.  
  1088.  
  1089. static void auth_init(qp, recip)
  1090. Q_struct *qp;
  1091. ADDR *recip;
  1092. {
  1093.     char               *argv[MAX_AUTH_ARGS], 
  1094.                 *cp;
  1095.     int            argc;
  1096.     ADDR               *ad;
  1097.  
  1098.  
  1099.     PP_TRACE (("auth_init: authloglevel='%s' authchannel='%s'",
  1100.         authloglevel, authchannel));
  1101.  
  1102.     bzero (auth2submit_msg, BUFSIZ);
  1103.  
  1104.  
  1105.     switch (auth_loglev = cmd_srch (authloglevel, authtbl_loglevel)) {
  1106.     case AUTH_LOGLEVEL_LOW:
  1107.     case AUTH_LOGLEVEL_MEDIUM:
  1108.     case AUTH_LOGLEVEL_HIGH:
  1109.         break;
  1110.     default:
  1111.         auth_loglev = AUTH_LOGLEVEL_LOW;
  1112.         PP_LOG (LLOG_EXCEPTIONS,
  1113.             ("auth_init/authloglevel invalid : '%s' (low assumed)",
  1114.              authloglevel));
  1115.         break;
  1116.     }
  1117.  
  1118.  
  1119.     cp = strdup (authchannel);
  1120.  
  1121.     if ((argc = sstr2arg (cp, MAX_AUTH_ARGS, argv, " \t,")) == NOTOK)
  1122.         err_abrt (RP_NAUTH, "auth_init/authchannel invalid '%s'",
  1123.             authchannel);
  1124.  
  1125.     def_authchan = authchan_new (NULLCHAN, NULLIST_AUTHCHAN);
  1126.     tb_parse_authchan (def_authchan, argc, argv);
  1127.  
  1128.     sender_auth         = auth_new(qp -> msgtype == MT_DMPDU);
  1129.  
  1130.     authmta_start        = authmta_new (qp -> inbound -> li_mta);
  1131.     sender_auth -> mta    = authmta_start;
  1132.  
  1133. #ifdef notdef
  1134.     auth_mta (sender_auth -> mta);
  1135. #endif
  1136.  
  1137.     sender_auth -> user    = authusr_new();
  1138.  
  1139.     for (ad = recip; ad; ad = ad -> ad_next)
  1140.         auth_init_recip (qp, ad);
  1141.  
  1142.     free (cp);
  1143. }
  1144.  
  1145.  
  1146.  
  1147.  
  1148. static void auth_init_recip (qp, ad)
  1149. Q_struct *qp;
  1150. ADDR    *ad;
  1151. {
  1152.     AUTH_USER         *up;
  1153.     LIST_RCHAN         *lr;
  1154.     LIST_AUTH_CHAN        *lc;
  1155.     LIST_AUTH_MTA         *lm;
  1156.     int            found = FALSE;
  1157.     char            *val;
  1158.  
  1159.  
  1160.     PP_TRACE (("auth_init_recip (%s)", gval (ad)));
  1161.  
  1162.     up = authusr_new();
  1163.  
  1164.     for (lr = ad -> ad_outchan; lr; lr = lr -> li_next) {
  1165.  
  1166.         lr -> li_auth         = auth_new(qp -> msgtype == MT_DMPDU);
  1167.         lr -> li_auth -> user     = up;
  1168.         val             = lr -> li_chan -> ch_name;
  1169.         found            = FALSE;
  1170.  
  1171.         for (lc = authchan_start; lc; lc = lc -> li_next)
  1172.             if (strcmp (val, lc -> li_chan -> ch_name) == 0) {
  1173.                 found = TRUE;
  1174.                 break;
  1175.             }
  1176.  
  1177.         if (!found && lr -> li_chan) { 
  1178.             lc = authchan_new (lr -> li_chan, def_authchan);
  1179.             authchan_add (&authchan_start, lc);
  1180.         }
  1181.  
  1182.         lr -> li_auth -> chan     = lc;
  1183.         found             = FALSE;
  1184.  
  1185.         for (lm = authmta_start; lm; lm = lm -> li_next)
  1186.             if (strcmp (lm -> li_mta, lr -> li_mta) == 0) {
  1187.                 found = TRUE;
  1188.                 break;
  1189.             }
  1190.  
  1191.         if (!found && lr -> li_mta) {
  1192.             lm = authmta_new (lr -> li_mta);
  1193.             authmta_add (&authmta_start, lm);
  1194.         }
  1195.  
  1196.         lr -> li_auth -> mta    = lm;
  1197.     }
  1198. }
  1199.  
  1200.  
  1201.  
  1202.  
  1203. static void pr_rights (au, ch_policy, val)
  1204. AUTH    *au;
  1205. int    ch_policy, val;
  1206. {
  1207.     char    buf[BUFSIZ*2];
  1208.     char    *msg, *policy;
  1209.  
  1210.     PP_TRACE (("pr_rights ('%d')", ch_policy));
  1211.  
  1212.     switch (ch_policy) {
  1213.         case AUTH_CHAN_BLOCK:
  1214.         policy = "block";
  1215.         break;
  1216.         case AUTH_CHAN_NEGATIVE:
  1217.         policy = "negative";
  1218.         break;
  1219.         default:
  1220.         policy = "Unknown";
  1221.         break;
  1222.     }
  1223.     if (val == OK)
  1224.         msg = "Authorisation approved";
  1225.     else 
  1226.         switch (ch_policy) {
  1227.             case AUTH_CHAN_BLOCK:
  1228.             msg = "You are not authorised for this route";
  1229.             break;
  1230.             case AUTH_CHAN_NEGATIVE:
  1231.             msg = "You are prohibited from using this route";
  1232.             break;
  1233.             default:
  1234.             msg = "UnknownPolicy";
  1235.             break;
  1236.         }
  1237.     (void) sprintf (buf,
  1238. "%s: (policy %s, imta (%s %s) sender (%s %s) omta (%s %s) recip (%s %s))",
  1239.             msg, policy,
  1240.             rrights (sender_auth -> mta_inrights),
  1241.             rrights (sender_auth -> mta_outrights),
  1242.             rrights (sender_auth -> user_inrights),
  1243.             rrights (sender_auth -> user_outrights),
  1244.             rrights (au -> mta_inrights),
  1245.             rrights (au -> mta_outrights),
  1246.             rrights (au -> user_inrights),
  1247.             rrights (au -> user_outrights));
  1248.  
  1249.     do_reason (au, "%s", buf); 
  1250.     return;
  1251. }
  1252.  
  1253.  
  1254.  
  1255.  
  1256. static char *ltoa (l)
  1257. long    l;
  1258. {
  1259.         char    buf[LINESIZE];
  1260.  
  1261.         (void) sprintf (buf, "%ld", l);
  1262.         return (strdup (buf));
  1263. }
  1264.  
  1265.  
  1266.  
  1267.  
  1268. static int test_flags (f, val, type)
  1269. int    f[];
  1270. int    val;
  1271. int    type;
  1272. {
  1273.     switch (type) {
  1274.     case ORED:
  1275.         if (f[0] == val || f[1] == val || f[2] == val || f[3] == val)
  1276.             return OK;
  1277.         break;
  1278.     }
  1279.  
  1280.     return NOTOK;
  1281. }    
  1282.